package modelImp;

import java.awt.Image;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.util.Vector;


import ressources.Constant;
import model.ModelConstraint;
import model.ModelPosition;
import model.ModelTile;

public class Tile extends ModelTile {
	private Image image;

	
	public Tile(Image m, Tile[] neighbors, ModelConstraint[] north,ModelConstraint[] south,ModelConstraint[] east,ModelConstraint[] weast,Vector<ModelPosition> positions) throws Exception
	{
		if(north==null || south==null || east==null || weast==null)
			throw new Exception("Une tuile doit avoir ses 4 contraintes d'initialisé");
		this.constraints = new ModelConstraint[4][3];
		this.constraints[0] = north;
		this.constraints[1] = south;
		this.constraints[2] = east;
		this.constraints[3] = weast;
		this.image =m;
		this.neighbors = new Tile[4];
		this.positions = positions;
	}
	public Tile(){
		
	}
	
	public void rotate(){
		// Rotate image
		AffineTransform tx = new AffineTransform();
		tx.rotate(Math.toRadians(-90), this.image.getWidth(null) / 2, this.image.getHeight(null) / 2);	
		AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
		op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR);
		this.image = op.filter((BufferedImage) this.image, op.createCompatibleDestImage((BufferedImage) this.image, null) );
		
		// Rotate all constaints
		ModelConstraint[] tmp ;
		tmp =   this.constraints[Constant.NORTH];
		this.constraints[Constant.NORTH] = this.constraints[Constant.EAST];
		this.constraints[Constant.EAST] = this.constraints[Constant.SOUTH];
		this.constraints[Constant.SOUTH] = this.constraints[Constant.WEST];
		this.constraints[Constant.WEST] = tmp;
		
		// Rotate all positions
		/*for(ModelPosition position : this.positions){			
			Point2D original = new Point2D.Double(position.getPoint().getX(), position.getPoint().getY());
			AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(-90), this.image.getWidth(null)/2, this.image.getHeight(null)/2);
			Point2D rotated = at.transform(original, null);
			position.setPoint(new Point((int)rotated.getX(),(int)rotated.getX()));
			
			System.out.println("ancien="+position.getPoint());
			double angleDegre = -90;
			/*double angleRadian = Math.PI*angleDegre/180;
			double newx = position.getPoint().getX() * Math.cos(angleRadian) - position.getPoint().getY()*Math.sin(angleRadian)+39;
			double newy =  position.getPoint().getX() * Math.sin(angleRadian) + position.getPoint().getY()*Math.cos(angleRadian)+39;
			position.setPoint(new Point((int)newx,(int)newy));
			System.out.println("new="+position.getPoint());
		}*/
		
	}

	public Image getImage() {
		return image;
	}

	public Vector<ModelPosition> getPosition(){
		return this.positions;
	}
	

	@Override
	public boolean canPutTile(ModelTile[] neighbors) {
		if(neighbors==null)
			return false;
		if(neighbors[Constant.NORTH]== null &&
		   neighbors[Constant.SOUTH]== null &&
		   neighbors[Constant.WEST] == null &&
		   neighbors[Constant.EAST] == null)
			return false;
	
		if(neighbors[0]!=null && !(this.constraints[0][1].getName().equals(neighbors[0].getConstraint(1,1).getName())))
		{
			return false;
		}
		if(neighbors[1]!=null && !(this.constraints[1][1].getName().equals(neighbors[1].getConstraint(0,1).getName())))
		{
			return false;
		}
		if(neighbors[2]!=null && !(this.constraints[2][1].getName().equals(neighbors[2].getConstraint(3,1).getName())))
		{
			return false;
		}
		if(neighbors[3]!=null && !(this.constraints[3][1].getName().equals(neighbors[3].getConstraint(2,1).getName())))
		{
			return false;
		}
		
		return true;
		
	}
	
	public Tile[] getNeighbors(){
		return (Tile[]) this.neighbors;
	}
	
	private void setContraint(ModelConstraint oldconst, ModelConstraint newconst){
		
		for(int i=0;i<4;i++){
			for(int j=0;j<3;j++){
				if(this.constraints[i][j] == oldconst){
					this.constraints[i][j] = newconst;
				}
					
			}
		}
		for(int i=0;i<this.positions.size();i++){
			if(this.positions.get(i).getConstraint()==oldconst){
				this.positions.get(i).setConstraint(newconst);
			}
		}
		
	}
	public void setNeighbors(Tile[] neighbors){
		this.neighbors = neighbors;
		
		// Join north constraint
		if(neighbors[0]!=null){
			System.out.println("On remplace les contrainte nord");
			for(int i=0;i<3;i++){
				this.setContraint(this.constraints[0][i], neighbors[0].getConstraint(1, i));
			}
		}
		
		// Join sud constraint
		if(neighbors[1]!=null){
			for(int i=0;i<3;i++){
				this.setContraint(this.constraints[1][i], neighbors[1].getConstraint(0, i));
			}
		}
		
		// Join east constraint
		if(neighbors[2]!=null){
			System.out.println("On remplace les contrainte east");
			for(int i=0;i<3;i++){
				this.setContraint(this.constraints[2][i], neighbors[2].getConstraint(3, i));
			}
		
		}
		
		// Join north constraint
		if(neighbors[3]!=null){
			for(int i=0;i<3;i++){
				this.setContraint(this.constraints[3][i], neighbors[3].getConstraint(2, i));
			}
		
		}
		
		
		
	}
	
	
	
	
	
}
